#!/bin/bash
# Pre-Launch Checklist and Go-Live Script for ArXiv Subscription Platform

set -e

# Configuration
DOMAIN_NAME="${DOMAIN_NAME:-your-domain.com}"
STAGING_URL="${STAGING_URL:-https://staging.${DOMAIN_NAME}}"
PRODUCTION_URL="${PRODUCTION_URL:-https://${DOMAIN_NAME}}"
NOTIFICATION_EMAIL="${NOTIFICATION_EMAIL:-admin@${DOMAIN_NAME}}"
SLACK_WEBHOOK="${SLACK_WEBHOOK:-}"

# Test configuration
LOAD_TEST_USERS="${LOAD_TEST_USERS:-100}"
LOAD_TEST_DURATION="${LOAD_TEST_DURATION:-5m}"
PERFORMANCE_THRESHOLD_MS="${PERFORMANCE_THRESHOLD_MS:-500}"
ERROR_THRESHOLD_PERCENT="${ERROR_THRESHOLD_PERCENT:-1}"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
NC='\033[0m'

# Checklist tracking
CHECKLIST_FILE="/tmp/arxiv_checklist_$(date +%Y%m%d_%H%M%S).log"
FAILED_CHECKS=0
TOTAL_CHECKS=0

log() {
    echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$CHECKLIST_FILE"
}

warn() {
    echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1" | tee -a "$CHECKLIST_FILE"
}

error() {
    echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" | tee -a "$CHECKLIST_FILE"
    ((FAILED_CHECKS++))
}

info() {
    echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO:${NC} $1" | tee -a "$CHECKLIST_FILE"
}

success() {
    echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS:${NC} $1" | tee -a "$CHECKLIST_FILE"
}

check_item() {
    local item="$1"
    local command="$2"
    local description="$3"
    
    ((TOTAL_CHECKS++))
    info "Checking: $item"
    
    if eval "$command"; then
        success "✓ $item - $description"
        return 0
    else
        error "✗ $item - $description"
        return 1
    fi
}

send_notification() {
    local subject="$1"
    local message="$2"
    local urgency="${3:-normal}"
    
    # Email notification
    if command -v mail >/dev/null 2>&1 && [[ -n "$NOTIFICATION_EMAIL" ]]; then
        echo "$message" | mail -s "[$HOSTNAME] ArXiv Platform: $subject" "$NOTIFICATION_EMAIL"
    fi
    
    # Slack notification
    if [[ -n "$SLACK_WEBHOOK" ]]; then
        local color="good"
        local icon=":white_check_mark:"
        
        if [[ "$urgency" == "critical" ]]; then
            color="danger"
            icon=":rotating_light:"
        elif [[ "$urgency" == "warning" ]]; then
            color="warning"  
            icon=":warning:"
        fi
        
        curl -X POST -H 'Content-type: application/json' \
            --data "{\"text\":\"$icon $subject\",\"attachments\":[{\"color\":\"$color\",\"text\":\"$message\"}]}" \
            "$SLACK_WEBHOOK" 2>/dev/null || true
    fi
}

# Infrastructure Checks
check_infrastructure() {
    log "=== INFRASTRUCTURE CHECKS ==="
    
    check_item "Domain DNS Resolution" \
        "nslookup $DOMAIN_NAME | grep -q 'Address'" \
        "Domain resolves to correct IP"
    
    check_item "SSL Certificate Validity" \
        "echo | openssl s_client -servername $DOMAIN_NAME -connect $DOMAIN_NAME:443 2>/dev/null | openssl x509 -noout -dates" \
        "SSL certificate is valid and not expiring soon"
    
    check_item "HTTPS Redirect" \
        "curl -I http://$DOMAIN_NAME 2>/dev/null | head -1 | grep -q '301'" \
        "HTTP properly redirects to HTTPS"
    
    check_item "Security Headers" \
        "curl -I https://$DOMAIN_NAME 2>/dev/null | grep -q 'Strict-Transport-Security'" \
        "Security headers are present"
    
    check_item "Load Balancer Health" \
        "curl -f -s https://$DOMAIN_NAME/health >/dev/null" \
        "Load balancer is routing traffic correctly"
}

# Application Service Checks
check_services() {
    log "=== SERVICE HEALTH CHECKS ==="
    
    check_item "Backend API Health" \
        "curl -f -s $PRODUCTION_URL/api/health | jq -r '.status' | grep -q 'healthy'" \
        "Backend API is responding and healthy"
    
    check_item "Database Connectivity" \
        "curl -f -s $PRODUCTION_URL/api/health | jq -r '.database' | grep -q 'connected'" \
        "Database is accessible and responding"
    
    check_item "Redis Connectivity" \
        "curl -f -s $PRODUCTION_URL/api/health | jq -r '.redis' | grep -q 'connected'" \
        "Redis cache is accessible and responding"
    
    check_item "Email Service Health" \
        "curl -f -s $PRODUCTION_URL/api/health | jq -r '.email_service' | grep -q 'healthy'" \
        "Email service is operational"
    
    check_item "ArXiv Scraper Status" \
        "curl -f -s $PRODUCTION_URL/api/health | jq -r '.scraper_service' | grep -q 'healthy'" \
        "ArXiv scraper service is running"
    
    check_item "AI Classification Service" \
        "curl -f -s $PRODUCTION_URL/api/health | jq -r '.ai_classifier' | grep -q 'healthy'" \
        "AI classification service is operational"
}

# Security Checks
check_security() {
    log "=== SECURITY CHECKS ==="
    
    check_item "Rate Limiting Active" \
        "for i in {1..30}; do curl -s $PRODUCTION_URL/api/health >/dev/null; done; curl -I $PRODUCTION_URL/api/health 2>/dev/null | head -1 | grep -q '429'" \
        "Rate limiting is protecting API endpoints"
    
    check_item "Authentication Required" \
        "curl -s $PRODUCTION_URL/api/dashboard | jq -r '.error' | grep -q 'unauthorized'" \
        "Protected endpoints require authentication"
    
    check_item "SQL Injection Protection" \
        "curl -s \"$PRODUCTION_URL/api/papers/search?q='%20OR%201=1--\" | jq -r '.error' | grep -q -v 'database'" \
        "SQL injection attempts are blocked"
    
    check_item "XSS Protection Headers" \
        "curl -I $PRODUCTION_URL 2>/dev/null | grep -q 'X-XSS-Protection'" \
        "XSS protection headers are set"
    
    check_item "Content Security Policy" \
        "curl -I $PRODUCTION_URL 2>/dev/null | grep -q 'Content-Security-Policy'" \
        "Content Security Policy is configured"
}

# Performance Checks
check_performance() {
    log "=== PERFORMANCE CHECKS ==="
    
    # Response time check
    local response_time=$(curl -o /dev/null -s -w '%{time_total}\n' $PRODUCTION_URL)
    local response_time_ms=$(echo "$response_time * 1000" | bc -l | cut -d. -f1)
    
    check_item "Homepage Response Time" \
        "[[ $response_time_ms -lt $PERFORMANCE_THRESHOLD_MS ]]" \
        "Homepage loads in under ${PERFORMANCE_THRESHOLD_MS}ms (actual: ${response_time_ms}ms)"
    
    # API response time check
    local api_response_time=$(curl -o /dev/null -s -w '%{time_total}\n' $PRODUCTION_URL/api/health)
    local api_response_time_ms=$(echo "$api_response_time * 1000" | bc -l | cut -d. -f1)
    
    check_item "API Response Time" \
        "[[ $api_response_time_ms -lt 200 ]]" \
        "API responds in under 200ms (actual: ${api_response_time_ms}ms)"
    
    check_item "Static Asset Compression" \
        "curl -H 'Accept-Encoding: gzip' -I $PRODUCTION_URL/static/main.js 2>/dev/null | grep -q 'Content-Encoding: gzip'" \
        "Static assets are compressed"
    
    check_item "CDN/Caching Headers" \
        "curl -I $PRODUCTION_URL/static/main.js 2>/dev/null | grep -q 'Cache-Control'" \
        "Caching headers are properly set"
}

# Database Checks
check_database() {
    log "=== DATABASE CHECKS ==="
    
    check_item "Database Schema Version" \
        "curl -f -s $PRODUCTION_URL/api/health | jq -r '.database_version' | grep -q -v 'null'" \
        "Database schema is at expected version"
    
    check_item "Database Performance" \
        "curl -f -s $PRODUCTION_URL/api/health | jq -r '.database_response_time' | awk '{print (\$1 < 0.1)}' | grep -q '1'" \
        "Database queries respond quickly"
    
    check_item "Database Connection Pool" \
        "curl -f -s $PRODUCTION_URL/api/health | jq -r '.database_connections' | awk '{print (\$1 < 50)}' | grep -q '1'" \
        "Database connection pool is healthy"
    
    check_item "Backup System Status" \
        "find /var/backups/arxiv-platform -name '*.sql*' -mtime -1 | wc -l | awk '{print (\$1 > 0)}' | grep -q '1'" \
        "Recent database backups exist"
}

# Monitoring Checks
check_monitoring() {
    log "=== MONITORING CHECKS ==="
    
    check_item "Prometheus Metrics" \
        "curl -f -s $PRODUCTION_URL:9090/api/v1/query?query=up | jq -r '.status' | grep -q 'success'" \
        "Prometheus is collecting metrics"
    
    check_item "Grafana Dashboard" \
        "curl -f -s $PRODUCTION_URL:3001/api/health 2>/dev/null" \
        "Grafana dashboards are accessible"
    
    check_item "Alertmanager Status" \
        "curl -f -s $PRODUCTION_URL:9093/api/v1/status 2>/dev/null | jq -r '.status' | grep -q 'success'" \
        "Alertmanager is operational"
    
    check_item "Log Aggregation" \
        "find /var/log/arxiv-platform -name '*.log' -mtime -1 | wc -l | awk '{print (\$1 > 0)}' | grep -q '1'" \
        "Application logs are being collected"
}

# Functional Tests
run_functional_tests() {
    log "=== FUNCTIONAL TESTS ==="
    
    check_item "User Registration" \
        "curl -s -X POST $PRODUCTION_URL/api/auth/register -H 'Content-Type: application/json' -d '{\"email\":\"test@example.com\",\"password\":\"Test123!\"}' | jq -r '.status' | grep -q -E '(success|user_exists)'" \
        "User registration endpoint works"
    
    check_item "User Login" \
        "curl -s -X POST $PRODUCTION_URL/api/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"test@example.com\",\"password\":\"Test123!\"}' | jq -r '.access_token' | grep -q -v 'null'" \
        "User authentication works"
    
    check_item "Paper Search" \
        "curl -s '$PRODUCTION_URL/api/papers/search?q=machine%20learning&limit=5' | jq -r '.papers | length' | awk '{print (\$1 > 0)}' | grep -q '1'" \
        "Paper search returns results"
    
    check_item "Paper Details" \
        "curl -s '$PRODUCTION_URL/api/papers?limit=1' | jq -r '.papers[0].id' | xargs -I {} curl -s '$PRODUCTION_URL/api/papers/{}' | jq -r '.title' | grep -q -v 'null'" \
        "Paper details can be retrieved"
    
    check_item "Email System Test" \
        "curl -s -X POST $PRODUCTION_URL/api/test-email -H 'Content-Type: application/json' -d '{\"to\":\"test@example.com\",\"subject\":\"Test\",\"body\":\"Test\"}' | jq -r '.status' | grep -q 'sent'" \
        "Email system can send messages"
}

# Load Testing
run_load_tests() {
    log "=== LOAD TESTING ==="
    
    if ! command -v k6 >/dev/null 2>&1; then
        warn "k6 not installed, skipping load tests"
        return 0
    fi
    
    info "Running load test with $LOAD_TEST_USERS users for $LOAD_TEST_DURATION"
    
    local load_test_result="load_test_results_$(date +%Y%m%d_%H%M%S).json"
    
    # Run load test
    if BASE_URL="$PRODUCTION_URL" k6 run \
        --vus "$LOAD_TEST_USERS" \
        --duration "$LOAD_TEST_DURATION" \
        --summary-export "$load_test_result" \
        tests/performance/load_test.js; then
        
        success "Load test completed successfully"
        
        # Check results
        local avg_response_time=$(jq -r '.metrics.http_req_duration.values.avg' "$load_test_result" 2>/dev/null || echo "0")
        local error_rate=$(jq -r '.metrics.http_req_failed.values.rate' "$load_test_result" 2>/dev/null || echo "0")
        
        if (( $(echo "$avg_response_time < $PERFORMANCE_THRESHOLD_MS" | bc -l) )); then
            success "Average response time: ${avg_response_time}ms (under ${PERFORMANCE_THRESHOLD_MS}ms)"
        else
            error "Average response time: ${avg_response_time}ms (exceeds ${PERFORMANCE_THRESHOLD_MS}ms)"
        fi
        
        if (( $(echo "$error_rate < 0.01" | bc -l) )); then
            success "Error rate: $(echo "$error_rate * 100" | bc -l)% (under 1%)"
        else
            error "Error rate: $(echo "$error_rate * 100" | bc -l)% (exceeds 1%)"
        fi
        
    else
        error "Load test failed"
    fi
}

# Backup and Recovery Tests
test_backup_recovery() {
    log "=== BACKUP AND RECOVERY TESTS ==="
    
    check_item "Database Backup Creation" \
        "sudo -u postgres pg_dump -h localhost -U postgres arxiv_platform > /tmp/test_backup.sql 2>/dev/null" \
        "Database backup can be created"
    
    check_item "Backup File Integrity" \
        "head -1 /tmp/test_backup.sql | grep -q 'PostgreSQL database dump'" \
        "Backup file has valid format"
    
    # Clean up test backup
    rm -f /tmp/test_backup.sql
    
    check_item "Backup Automation" \
        "crontab -l | grep -q 'backup'" \
        "Automated backup jobs are scheduled"
    
    check_item "Log Rotation" \
        "ls /var/log/arxiv-platform/*.log.1 2>/dev/null | wc -l | awk '{print (\$1 > 0)}' | grep -q '1'" \
        "Log rotation is working"
}

# Final System Integration Test
run_integration_test() {
    log "=== INTEGRATION TEST ==="
    
    info "Running end-to-end user journey test..."
    
    # Create a test user
    local test_email="integration_test_$(date +%s)@example.com"
    local test_password="IntegrationTest123!"
    
    # Register user
    local register_response=$(curl -s -X POST $PRODUCTION_URL/api/auth/register \
        -H 'Content-Type: application/json' \
        -d "{\"email\":\"$test_email\",\"password\":\"$test_password\",\"first_name\":\"Test\",\"last_name\":\"User\"}")
    
    if echo "$register_response" | jq -r '.status' | grep -q 'success'; then
        success "User registration successful"
    else
        error "User registration failed: $register_response"
        return 1
    fi
    
    # Login user
    local login_response=$(curl -s -X POST $PRODUCTION_URL/api/auth/login \
        -H 'Content-Type: application/json' \
        -d "{\"email\":\"$test_email\",\"password\":\"$test_password\"}")
    
    local access_token=$(echo "$login_response" | jq -r '.access_token')
    
    if [[ "$access_token" != "null" && -n "$access_token" ]]; then
        success "User login successful"
    else
        error "User login failed: $login_response"
        return 1
    fi
    
    # Test authenticated endpoints
    local headers="Authorization: Bearer $access_token"
    
    # Get user dashboard
    local dashboard_response=$(curl -s -H "$headers" $PRODUCTION_URL/api/dashboard)
    if echo "$dashboard_response" | jq -r '.recommendations' | grep -q -v 'null'; then
        success "User dashboard loads with recommendations"
    else
        warn "User dashboard may not have recommendations yet (new user)"
    fi
    
    # Create a subscription
    local subscription_response=$(curl -s -X POST $PRODUCTION_URL/api/subscriptions \
        -H 'Content-Type: application/json' \
        -H "$headers" \
        -d '{"subscription_type":"category","subscription_target":"cs.AI","subscription_name":"AI Papers"}')
    
    if echo "$subscription_response" | jq -r '.id' | grep -q -v 'null'; then
        success "Subscription creation successful"
    else
        error "Subscription creation failed: $subscription_response"
    fi
    
    # Test paper search and interaction
    local search_response=$(curl -s -H "$headers" "$PRODUCTION_URL/api/papers/search?q=machine%20learning&limit=1")
    local paper_id=$(echo "$search_response" | jq -r '.papers[0].id')
    
    if [[ "$paper_id" != "null" && -n "$paper_id" ]]; then
        success "Paper search successful"
        
        # Bookmark the paper
        local bookmark_response=$(curl -s -X POST $PRODUCTION_URL/api/bookmarks \
            -H 'Content-Type: application/json' \
            -H "$headers" \
            -d "{\"paper_id\":\"$paper_id\"}")
        
        if echo "$bookmark_response" | jq -r '.id' | grep -q -v 'null'; then
            success "Paper bookmark successful"
        else
            warn "Paper bookmark may have failed: $bookmark_response"
        fi
    else
        error "Paper search failed: $search_response"
    fi
    
    # Clean up test user (optional in production)
    # curl -s -X DELETE $PRODUCTION_URL/api/auth/user -H "$headers" >/dev/null
    
    success "Integration test completed"
}

# Generate final report
generate_report() {
    local end_time=$(date)
    local passed_checks=$((TOTAL_CHECKS - FAILED_CHECKS))
    local success_rate=$((passed_checks * 100 / TOTAL_CHECKS))
    
    log "=== FINAL REPORT ==="
    
    local report_file="pre_launch_report_$(date +%Y%m%d_%H%M%S).html"
    
    cat > "$report_file" << EOF
<!DOCTYPE html>
<html>
<head>
    <title>ArXiv Platform Pre-Launch Report</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 20px; }
        .header { background: #f0f0f0; padding: 20px; border-radius: 5px; }
        .section { margin: 20px 0; }
        .success { color: green; }
        .error { color: red; }
        .warning { color: orange; }
        .metric { display: inline-block; margin: 10px; padding: 10px; background: #f9f9f9; border-radius: 5px; }
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <div class="header">
        <h1>ArXiv Subscription Platform - Pre-Launch Report</h1>
        <p><strong>Generated:</strong> $end_time</p>
        <p><strong>Domain:</strong> $DOMAIN_NAME</p>
        <p><strong>Environment:</strong> Production</p>
    </div>
    
    <div class="section">
        <h2>Summary</h2>
        <div class="metric">
            <strong>Total Checks:</strong> $TOTAL_CHECKS
        </div>
        <div class="metric">
            <strong>Passed:</strong> <span class="success">$passed_checks</span>
        </div>
        <div class="metric">
            <strong>Failed:</strong> <span class="error">$FAILED_CHECKS</span>
        </div>
        <div class="metric">
            <strong>Success Rate:</strong> ${success_rate}%
        </div>
    </div>
    
    <div class="section">
        <h2>Detailed Results</h2>
        <pre>$(cat "$CHECKLIST_FILE")</pre>
    </div>
    
    <div class="section">
        <h2>Recommendations</h2>
EOF

    if [[ $FAILED_CHECKS -eq 0 ]]; then
        echo "<p class='success'>✓ All checks passed! Platform is ready for launch.</p>" >> "$report_file"
    elif [[ $FAILED_CHECKS -le 2 ]]; then
        echo "<p class='warning'>⚠ Minor issues detected. Review failed checks before launch.</p>" >> "$report_file"
    else
        echo "<p class='error'>✗ Multiple critical issues detected. DO NOT launch until resolved.</p>" >> "$report_file"
    fi
    
    cat >> "$report_file" << EOF
    </div>
    
    <div class="section">
        <h2>Next Steps</h2>
        <ul>
            <li>Review all failed checks and resolve issues</li>
            <li>Run additional load testing if needed</li>
            <li>Verify monitoring and alerting systems</li>
            <li>Prepare rollback plan</li>
            <li>Schedule launch window</li>
            <li>Notify stakeholders of launch status</li>
        </ul>
    </div>
</body>
</html>
EOF

    info "Detailed report generated: $report_file"
    
    # Send notification
    local status="SUCCESS"
    local urgency="normal"
    
    if [[ $FAILED_CHECKS -gt 2 ]]; then
        status="CRITICAL ISSUES FOUND"
        urgency="critical"
    elif [[ $FAILED_CHECKS -gt 0 ]]; then
        status="MINOR ISSUES FOUND"
        urgency="warning"
    fi
    
    local message="Pre-launch checklist completed.
    
Total Checks: $TOTAL_CHECKS
Passed: $passed_checks
Failed: $FAILED_CHECKS
Success Rate: ${success_rate}%

$(if [[ $FAILED_CHECKS -eq 0 ]]; then echo "✓ Platform is ready for launch!"; else echo "⚠ Review failed checks before launch."; fi)

Full report: $report_file"
    
    send_notification "Pre-Launch Checklist: $status" "$message" "$urgency"
    
    if [[ $FAILED_CHECKS -eq 0 ]]; then
        log "🚀 ALL CHECKS PASSED! ArXiv Subscription Platform is ready for launch!"
        return 0
    else
        log "❌ $FAILED_CHECKS checks failed. Review and resolve issues before launch."
        return 1
    fi
}

# Main execution
main() {
    log "Starting pre-launch checklist for ArXiv Subscription Platform..."
    log "Target domain: $DOMAIN_NAME"
    log "Production URL: $PRODUCTION_URL"
    
    # Run all check categories
    check_infrastructure
    check_services
    check_security
    check_performance
    check_database
    check_monitoring
    run_functional_tests
    test_backup_recovery
    run_load_tests
    run_integration_test
    
    # Generate final report
    generate_report
}

# Script execution with options
case "${1:-full}" in
    "full")
        main
        ;;
    "infrastructure")
        check_infrastructure
        ;;
    "services")
        check_services
        ;;
    "security")
        check_security
        ;;
    "performance")
        check_performance
        ;;
    "database")
        check_database
        ;;
    "monitoring")
        check_monitoring
        ;;
    "functional")
        run_functional_tests
        ;;
    "load")
        run_load_tests
        ;;
    "integration")
        run_integration_test
        ;;
    "backup")
        test_backup_recovery
        ;;
    *)
        echo "Usage: $0 {full|infrastructure|services|security|performance|database|monitoring|functional|load|integration|backup}"
        echo ""
        echo "  full           - Run all checks (default)"
        echo "  infrastructure - Check DNS, SSL, load balancer"
        echo "  services       - Check application services health"
        echo "  security       - Check security configurations"
        echo "  performance    - Check response times and optimization"
        echo "  database       - Check database health and backups"
        echo "  monitoring     - Check monitoring systems"
        echo "  functional     - Run functional API tests"
        echo "  load           - Run load testing"
        echo "  integration    - Run end-to-end integration test"
        echo "  backup         - Test backup and recovery systems"
        exit 1
        ;;
esac